/**
 * 'CalendaringGUI.fxml' Controller Class
 * 
 * @author nisoda, shultzam
 */

package application;

import java.net.URL;
import java.util.ResourceBundle;
import javafx.fxml.FXML;
import javafx.scene.control.Button;
import javafx.scene.control.ChoiceBox;
import javafx.scene.control.ComboBox;
import javafx.scene.control.Label;
import javafx.scene.control.RadioButton;
import javafx.scene.control.TextField;
import javafx.scene.control.ToggleGroup;
import javafx.scene.layout.AnchorPane;
import javafx.event.*;

public class Controller {

	

    @FXML // ResourceBundle that was given to the FXMLLoader
    private ResourceBundle resources;

    @FXML // URL location of the FXML file that was given to the FXMLLoader
    private URL location;

    @FXML // fx:id="ExportCal"
    private Button ExportCal; // Value injected by FXMLLoader

    @FXML // fx:id="EndAmPm"
    private ChoiceBox<?> EndAmPm; // Value injected by FXMLLoader

    @FXML // fx:id="CalName"
    private TextField CalName; // Value injected by FXMLLoader

    @FXML // fx:id="StrtYear"
    private ComboBox<?> StrtYear; // Value injected by FXMLLoader

    @FXML // fx:id="StrtDay"
    private ComboBox<?> StrtDay; // Value injected by FXMLLoader

    @FXML // fx:id="Latitude"
    private TextField Latitude; // Value injected by FXMLLoader

    @FXML // fx:id="ClassConf"
    private RadioButton ClassConf; // Value injected by FXMLLoader

    @FXML // fx:id="EndHour"
    private ComboBox<?> EndHour; // Value injected by FXMLLoader

    @FXML // fx:id="ClassPub"
    private RadioButton ClassPub; // Value injected by FXMLLoader

    @FXML // fx:id="AddEvent"
    private Button AddEvent; // Value injected by FXMLLoader
    
    @FXML // fx:id="EndDay"
    private ComboBox<?> EndDay; // Value injected by FXMLLoader

    @FXML // fx:id="StrtMin"
    private ComboBox<?> StrtMin; // Value injected by FXMLLoader

    @FXML // fx:id="StrtMonth"
    private ComboBox<?> StrtMonth; // Value injected by FXMLLoader

    @FXML // fx:id="AddStatus"
    private Label AddStatus; // Value injected by FXMLLoader
    
    @FXML // fx:id="ExportStatus"
    private Label ExportStatus; // Value injected by FXMLLoader

    @FXML // fx:id="StrtHour"
    private ComboBox<?> StrtHour; // Value injected by FXMLLoader

    @FXML // fx:id="Priority"
    private ComboBox<?> Priority; // Value injected by FXMLLoader

    @FXML // fx:id="NumEventsStatus"
    private Label NumEventsStatus; // Value injected by FXMLLoader

    @FXML // fx:id="EndMin"
    private ComboBox<?> EndMin; // Value injected by FXMLLoader

    @FXML // fx:id="Longitude"
    private TextField Longitude; // Value injected by FXMLLoader

    @FXML // fx:id="ClassRadioGroup"
    private ToggleGroup ClassRadioGroup; // Value injected by FXMLLoader

    @FXML // fx:id="EndMonth"
    private ComboBox<?> EndMonth; // Value injected by FXMLLoader

    @FXML // fx:id="StrtAmPm"
    private ChoiceBox<?> StrtAmPm; // Value injected by FXMLLoader

    @FXML // fx:id="EndYear"
    private ComboBox<?> EndYear; // Value injected by FXMLLoader

    @FXML // fx:id="EventSummary"
    private TextField EventSummary; // Value injected by FXMLLoader

    @FXML // fx:id="ClassPriv"
    private RadioButton ClassPriv; // Value injected by FXMLLoader
    
    @FXML // fx:id="ClearAll"
    private Button ClearAll; //Value injected by FXMLLoader
    
    @FXML // fx:id="TimeZone"
    private ComboBox<?> TimeZone; // Value injected by FXMLLoader
    
    private Calendar myCal;

    @FXML // This method is called by the FXMLLoader when initialization is complete
    void initialize() {
        assert ExportCal != null : "fx:id=\"ExportCal\" was not injected: check your FXML file 'CalendaringGUI.fxml'.";
        assert EndAmPm != null : "fx:id=\"EndAmPm\" was not injected: check your FXML file 'CalendaringGUI.fxml'.";
        assert CalName != null : "fx:id=\"CalName\" was not injected: check your FXML file 'CalendaringGUI.fxml'.";
        assert StrtYear != null : "fx:id=\"StrtYear\" was not injected: check your FXML file 'CalendaringGUI.fxml'.";
        assert StrtDay != null : "fx:id=\"StrtDay\" was not injected: check your FXML file 'CalendaringGUI.fxml'.";
        assert Latitude != null : "fx:id=\"Latitude\" was not injected: check your FXML file 'CalendaringGUI.fxml'.";
        assert ClassConf != null : "fx:id=\"ClassConf\" was not injected: check your FXML file 'CalendaringGUI.fxml'.";
        assert EndHour != null : "fx:id=\"EndHour\" was not injected: check your FXML file 'CalendaringGUI.fxml'.";
        assert ClassPub != null : "fx:id=\"ClassPub\" was not injected: check your FXML file 'CalendaringGUI.fxml'.";
        assert AddEvent != null : "fx:id=\"AddEvent\" was not injected: check your FXML file 'CalendaringGUI.fxml'.";
        assert EndDay != null : "fx:id=\"EndDay\" was not injected: check your FXML file 'CalendaringGUI.fxml'.";
        assert StrtMin != null : "fx:id=\"StrtMin\" was not injected: check your FXML file 'CalendaringGUI.fxml'.";
        assert StrtMonth != null : "fx:id=\"StrtMonth\" was not injected: check your FXML file 'CalendaringGUI.fxml'.";
        assert AddStatus != null : "fx:id=\"AddStatus\" was not injected: check your FXML file 'CalendaringGUI.fxml'.";
        assert ExportStatus != null : "fx:id=\"ExportStatus\" was not injected: check your FXML file 'CalendaringGUI.fxml'.";
        assert StrtHour != null : "fx:id=\"StrtHour\" was not injected: check your FXML file 'CalendaringGUI.fxml'.";
        assert Priority != null : "fx:id=\"Priority\" was not injected: check your FXML file 'CalendaringGUI.fxml'.";
        assert NumEventsStatus != null : "fx:id=\"NumEventsStatus\" was not injected: check your FXML file 'CalendaringGUI.fxml'.";
        assert EndMin != null : "fx:id=\"EndMin\" was not injected: check your FXML file 'CalendaringGUI.fxml'.";
        assert Longitude != null : "fx:id=\"Longitude\" was not injected: check your FXML file 'CalendaringGUI.fxml'.";
        assert ClassRadioGroup != null : "fx:id=\"ClassRadioGroup\" was not injected: check your FXML file 'CalendaringGUI.fxml'.";
        assert EndMonth != null : "fx:id=\"EndMonth\" was not injected: check your FXML file 'CalendaringGUI.fxml'.";
        assert StrtAmPm != null : "fx:id=\"StrtAmPm\" was not injected: check your FXML file 'CalendaringGUI.fxml'.";
        assert EndYear != null : "fx:id=\"EndYear\" was not injected: check your FXML file 'CalendaringGUI.fxml'.";
        assert EventSummary != null : "fx:id=\"EventSummary\" was not injected: check your FXML file 'CalendaringGUI.fxml'.";
        assert ClassPriv != null : "fx:id=\"ClassPriv\" was not injected: check your FXML file 'CalendaringGUI.fxml'.";
        assert ClearAll != null : "fx:id=\"ClearAll\" was not injected: check your FXML file 'CalendaringGUI.fxml'.";
        assert TimeZone != null : "fx:id=\"TimeZone\" was not injected: check your FXML file 'CalendaringGUI.fxml'.";
        
        myCal = new Calendar();
        
        AddEvent.setOnAction(new EventHandler<ActionEvent>() {
        	
        	@Override
        	public void handle(ActionEvent e) {
        		
        		//Try-catch to verify all required fields are not empty
        		try {
        			String strtMonth = StrtMonth.getValue().toString().substring(0, 2);
        			String strtDay = StrtDay.getValue().toString();
        			String strtYear = StrtYear.getValue().toString();
        			String endMonth = EndMonth.getValue().toString().substring(0, 2);
        			String endDay = EndDay.getValue().toString();
        			String endYear = EndYear.getValue().toString();
        			String strtHour = StrtHour.getValue().toString();
        			String strtMin = StrtMin.getValue().toString();
        			String strtAMPM = StrtAmPm.getValue().toString();
        			String endHour = EndHour.getValue().toString();
        			String endMin = EndMin.getValue().toString();
        			String endAMPM = EndAmPm.getValue().toString();
        			String summary = new String();
        			String dStart = new String();
        			String tStart = new String();
        			String dEnd = new String();
        			String tEnd = new String();
        			int eventPriority = 0;
        			String lati = new String();
        			String longi = new String();
        			String classif = new String();

        			summary = EventSummary.getText();

        			//Create a CalEvent object with the given Event Summary
        			CalEvent event = new CalEvent(summary);
        		
        			//Set values in CalEvent
        			if(!validDate(strtMonth, strtDay, strtYear)) {
        				AddStatus.setText("EVENT NOT ADDED: Invalid Start Date.");
        				return;
        			}
        			else {
        				dStart = determineDate(strtMonth, strtDay, strtYear);
        			}
        			
        			if(!validDate(endMonth, endDay, endYear)) {
        				AddStatus.setText("EVENT NOT ADDED: Invalid End Date.");
        				return;
        			}
        			else {
        				dEnd = determineDate(endMonth, endDay, endYear);
        			}
        			
        			tStart = formatTime(strtHour, strtMin, strtAMPM);
        			tEnd = formatTime(endHour, endMin, endAMPM);
        			
        			if(!validStart(dStart, tStart, dEnd, tEnd)) {
        				AddStatus.setText("EVENT NOT ADDED: Start Date/Time is after End Date/Time");
        				return;
        			}
        			
        			eventPriority = Integer.parseInt(Priority.getValue().toString());
        			System.out.println("Event Priority: " + eventPriority);
        			
        			try {
        				lati = Latitude.getText();
        				System.out.println("Latitude: " + lati);
        			
        				longi = Longitude.getText();
        				System.out.println("Longitude: " + longi);
        				
        				if(!validLati(Float.parseFloat(lati))) {
            				AddStatus.setText("EVENT NOT ADDED: Invalid Latitude.");
            				return;
            			}
            			
            			if(!validLongi(Float.parseFloat(longi))) {
            				AddStatus.setText("EVENT NOT ADDED: Invalid Longitude.");
            				return;
            			}
            			
            			event.setGeo(Float.parseFloat(lati), Float.parseFloat(longi));
        			}
        			catch (Exception except) {
        				System.out.println("No Latitude/Longitude detected.");
        			}        			
        			
        			classif = ((RadioButton)ClassRadioGroup.getSelectedToggle()).getText();
        			System.out.println(classif);
        			
        			event.setDTStart(dStart, tStart);
        			event.setDTEnd(dEnd, tEnd);
        			event.setClassif(classif);
        			event.setPriority(eventPriority);
        			
        			System.out.println("Event added.");
        			
	        		//Add newly created CalEvent to the calendar
	        		myCal.addEvent(event);
	        		
        			AddStatus.setText("Success!");
        			NumEventsStatus.setText(myCal.numEvents() + " events");
        		}
        		catch (Exception except) {
        			AddStatus.setText("EVENT NOT ADDED: Check required fields.");
        			return;
        		}        		
        	}
        });
        
       ClearAll.setOnAction(new EventHandler<ActionEvent>() {
        	@Override
        	public void handle(ActionEvent e) {
    			try {
    				EventSummary.clear();
    				StrtMonth.getSelectionModel().clearSelection();
    				StrtDay.getSelectionModel().clearSelection();
    				StrtYear.getSelectionModel().clearSelection();
    				StrtHour.getSelectionModel().clearSelection();
    				StrtMin.getSelectionModel().clearSelection();
    				StrtAmPm.getSelectionModel().clearSelection();
    				EndMonth.getSelectionModel().clearSelection();
    				EndDay.getSelectionModel().clearSelection();
    				EndYear.getSelectionModel().clearSelection();
    				EndHour.getSelectionModel().clearSelection();
    				EndMin.getSelectionModel().clearSelection();
    				EndAmPm.getSelectionModel().clearSelection();
    				Priority.getSelectionModel().clearAndSelect(0);
    				Latitude.clear();
    				Longitude.clear();
    				ClassRadioGroup.selectToggle(ClassPub);
    			}
    			catch (Exception event){
    				return;
    			}
    			
    			
        	}
        });
        
        ExportCal.setOnAction(new EventHandler<ActionEvent>() {
        	@Override
        	public void handle(ActionEvent e) {
    			
        		//Try-catch to verify all required fields are not empty
        		try {
        			if(myCal.numEvents() == 0) {
        				ExportStatus.setText("CALENDAR NOT EXPORTED: No events in Calendar.");
        				return;
        			}
        			
        			String tzName= new String();
        			tzName = TimeZone.getValue().toString().substring(0, 4).trim();
        			myCal.setTZInfo(tzName);
        			
        			if(CalName.getText().length() != 0) {
        				myCal.setCalName(CalName.getText());
        				
	        			myCal.exportCal();
	        			ExportStatus.setText("Success!");
        			}
        			else {
        				ExportStatus.setText("CALENDAR NOT EXPORTED: Calendar Name required.");
        				return;
        			}
        			
        		}
        		catch (Exception except) {
        			ExportStatus.setText("CALENDAR NOT EXPORTED.");
        			return;
        		}        		
        	}
        });

    }
    
    /*
     * Determines if a date by given parameters is valid (i.e. Feb has 28 days, etc.).
     * 
     * @param	String month	Parameter month
     * 			String day		Parameter day
     * 			String year		Parameter year		  
     * @return	boolean	valid	Returns TRUE if the given date is valid, FALSE otherwise.
     * 
     */
    public static boolean validDate(String month, String day, String year) {
    	boolean valid = false;
    	
    	System.out.println("Validating Date...");
    	
    	if(((Integer.parseInt(year) % 4) == 0 ) && (month.compareTo("02") == 0)) {
    		if(Integer.parseInt(day) <= 29) {
    			valid = true;
    		}
    	}
    	else {
    		switch(month) {
	    		case "01" :
	    		case "03" :
	    		case "05" :
	    		case "07" :
	    		case "08" :
	    		case "10" :
	    		case "12" : valid = true;
							break;
	    		case "04" :
	    		case "06" :
	    		case "09" :
	    		case "11" : if(Integer.parseInt(day) <= 30) {
								valid = true;
							}
				    		else {
				    			valid = false;
				    		}
	    					break;
	    		case "02" : if(Integer.parseInt(day) <= 28) {
								valid = true;
							}
				    		else {
				    			valid = false;
				    		}
							break;
				default : valid = false;
						  break;
    		}
    	}
    	
    	if(valid) {
    		System.out.println("Date validated.");
    	}
    	else {
    		System.out.println("Date could not be validated.");
    	}
    	return valid;
    }
    
    /*
     * Formats date by given parameters in the following format: YYYYMMDD.
     * 
     * @param	String month	Parameter month
     * 			String day		Parameter day
     * 			String year		Parameter year		  
     * @return	String saveDate	Date in the following format: YYYYMMDD
     */
     public static String determineDate(String month, String day, String year) {
    	 String saveDate = new String();
    	 saveDate = year + month + day;
    	 
    	 System.out.println("Date Saved: " + saveDate);
    	 
    	 return saveDate;
     }
    /*
     * Formats 12-hour time by given parameters in 24-hour time in the 
     * following format: HHMM00
     * 
     * @param	String hours	Parameter hours (12-hour time)
     * 			String mins		Parameter minutes
     * 			String amPM		Parameter AM or PM
     * @return	String milTime	Returns the date in 24-hour time  in the 
     * 							following format: HHMM00
     */
    public static String formatTime(String hours, String mins, String amPM) {
    	String milTime = new String();
    	
    	switch(amPM) {
	    	case "AM" : if(hours.compareTo("12") != 0) {
							milTime = hours + mins;
						}
				    	else {
				    		milTime = "00" + mins;
				    	}
	    				System.out.println("Time saved: " + milTime);
	    				break;
	    	case "PM" : if(hours.compareTo("12") != 0) {
	    					milTime = (Integer.parseInt(hours) + 12) + mins;
	    				}
				    	else {
				    		milTime = hours + mins;
				    	}
	    				System.out.println("Time saved: " + milTime);
	    				break;
	    	default   : return milTime;
    	}
    	    	
    	return milTime;
    }
    
    /*
     * Determines if Start date/time is before End date/time.
     * 
     * @param	String dStart	Proposed Start date
     * 			String tStart	Proposed Start time
     * 			String dEnd		Proposed End date
     * 			String tEnd		Proposed End time
     * @return	boolean valid	Returns TRUE if Start date/time is before 
     * 							End date/time, FALSE otherwise.
     */
    public static boolean validStart(String dStart, String tStart, String dEnd, String tEnd) {
    	boolean valid = false;
    	int dateStart = Integer.parseInt(dStart);
    	System.out.println("Validating Start Date/Time is before End Date/Time...");
    	
    	if(dateStart < Integer.parseInt(dEnd)) {
    		System.out.println("Start Date/Time is before End Date/Time.");
    		valid = true;
    	}
    	else if((Integer.parseInt(dStart)) == (Integer.parseInt(dEnd)) && 
    			((Integer.parseInt(tStart)) < (Integer.parseInt(tEnd)))) {
    		System.out.println("Start Date/Time is before End Date/Time.");
    		valid = true;
    	}
    	else {
    		System.out.println("Start Date/Time is not before End Date/Time.");
    		valid = false;
    	}
    	
    	return valid;
    }
    
    
    /*
     * Determines if value is a valid Latitude.
     * 
     * @param	float lati	Parameter latitude
     * @return	boolean valid	Returns TRUE if latitude is valid,
     * 							FALSE otherwise.
     */
    public static boolean validLati(float lati) {
    	boolean valid = false;
    	
    	if((lati >= -90.0) && (lati <= 90.0))  {
    		valid = true;
    	}
    	
    	return valid;    	
    }
    
    /*
     * Determines if value is a valid Longitude.
     * 
     * @param	float longi	Parameter longitude
     * @return	boolean valid	Returns TRUE if longitude is valid,
     * 							FALSE otherwise.
     */
    public static boolean validLongi(float longi) {
    	boolean valid = false;
    	
    	if((longi >= -180.0) && (longi <= 180.0))  {
    		valid = true;
    	}
    	
    	return valid;    	
    	
    }
}
